import { MBErrorCode, MBKickoutCode, MBSocketEvent } from './module/mb_constants';
import MBCore from './module/mb_core'
import MBDataSender from './module/mb_data_sender'

class IMSDK {
    public _online: boolean = false;
    public _logined: boolean = false;
    public _debugSDKEnable: boolean = false;
    public _debugPingPongEnable: boolean = false;
    public callback_onIMLog: any = null;
    public callback_onIMData: any = null;
    public callback_onIMAfterLoginSucess: any = null;
    public callback_onIMReconnectSucess: any = null;
    public callback_onIMDisconnected: any = null;
    public callback_onIMAfterLoginFailed: any = null;
    public callback_onIMPing: any = null;
    public callback_onIMPong: any = null;
    public callback_onIMShowAlert: any = null;
    public callback_onIMKickout: any = null;
    public callback_onMessagesLost: any = null;
    public callback_onMessagesBeReceived: any = null;

    isLogined() {
        return this._logined;
    }

    isOnline() {
        return this._online;
    }

    getLoginInfo() {

        return MBCore.getCurrentLoginInfo();
    }
    sendData(p: any) {
        return MBDataSender.sendCommonData(p);
    }


    disconnectSocket() {
        var code = MBErrorCode.COMMON_UNKNOW_ERROR;
        if (MBCore.getCurrentLoginInfo() != null) {
            code = MBDataSender.sendLoginout();
            if (code === 0)
                this.callback_onIMLog('[SDK]  注销登陆请求已成功发出！', true);
            else
                this.callback_onIMLog("[SDK]  注销登陆请求发送失败。错误码是：" + code + "！", true);
        }
        else {
            MBCore.release();
        }

        this._logined = false;
    }


    setDebugCoreEnable(enable: any) {
        // 设置debug允许标识
        MBCore.setDebugEnabled(enable);
    }

    setDebugSDKEnable(enable: any) {
        // 设置debug允许标识
        this._debugSDKEnable = enable;
    }

    

    setDebugPingPongEnable(enable: any) {
        // 设置debug允许标识
        this._debugPingPongEnable = enable;
    }

    loginImpl(varloginInfo: any, wsUrl: any) {

        if (varloginInfo && wsUrl) {
            var that = this;
            MBCore.setWebsocketUrl(wsUrl);
            MBCore.on(MBSocketEvent.SOCKET_EVENT_ON_LOGIN_RESPONSE, (loginInfoResponse: any) => {
                if (loginInfoResponse) {

                    var code = loginInfoResponse.code;
                    if (that._debugSDKEnable) {
                        that.callback_onIMLog('[SDK]  本客户端 SOCKET_EVENT_ON_LOGIN_RESPONSE 事件已经触发（code=' + code + '）', true);
                    }

                    if (0 === code) {// 每次掉线都会重新走一遍认证过程
                        if (that._debugSDKEnable) {
                            that.callback_onIMLog('[SDK]  本客户端 SOCKET_EVENT_ON_LOGIN_RESPONSE 事件中：登陆认证成功('
                                + (that._logined ? '掉线重连' : '首次登陆') + ')！【code=' + code + '】', true);
                        }
                        that._online = true;
                        var welcome = '';
                        if (!that._logined) {
                            if(that.callback_onIMAfterLoginSucess){
                                that.callback_onIMAfterLoginSucess();
                            }
                          
                            welcome = "[SDK]  ● ● ● ● ●【已成功登陆至 MobileIMSDK 服务器】● ● ● ● ●";
                            that.callback_onIMLog(welcome, true);
                            this._logined = true;
                        }
                        // 掉线重连成功
                        else {
                            // Display the welcome message
                            welcome = "[SDK]  ○ ○ ○ ○ ○【已成功重连至 MobileIMSDK 服务器】○ ○ ○ ○ ○";
                            this.callback_onIMLog(welcome, true);

                            // 通知应用层对掉线重连成功结果处理展现或处理
                            that.callback_onIMReconnectSucess();
                        }
                    }
                    // 未认证成功（认证失败了）
                    else {
                        // 首次登陆时认证失败
                        if (!this._logined) {
                            if (this.callback_onIMAfterLoginFailed) {
                                this.callback_onIMAfterLoginFailed(false);
                            }

                            if (this._debugSDKEnable) {
                                this.callback_onIMLog("[SDK]  登陆认证失败，请检查您的用户名或密码！");
                            }
                        }
                        // 掉线重连时的认证失败
                        else {
                            var alertContent = '掉线重连时认证失败，请退出后重新登陆。。。';
                            // 如果开发者自已设置信息提示回调实现，就优先用开发者设置的
                            if (this.callback_onIMShowAlert) {
                                this.callback_onIMShowAlert(alertContent);
                            }
                            // 否则用浏览器默认的alert方法（就是UI有点土）
                            else {
                                window.alert(alertContent);
                            }

                            if (this.callback_onIMAfterLoginFailed) {
                                this.callback_onIMAfterLoginFailed(true);
                            }
                        }

                        if (this._debugSDKEnable) {
                            this.callback_onIMLog('[SDK]  本客户端的 SOCKET_EVENT_ON_LOGIN_RESPONSE 事件中：登陆认证失败【code=' + code + '】', true);
                        }
                    }
                }
                else {
                    this.callback_onIMLog('[SDK]  本客户端的 SOCKET_EVENT_ON_LOGIN_RESPONSE 事件成功返回，但返回的loginInfoResponse是空的！', true);
                }
            });


            MBCore.on(MBSocketEvent.SOCKET_EVENT_ON_LINK_CLOSE, (code: any) => {
                if (this._debugSDKEnable) {
                    this.callback_onIMLog('[SDK]  本客户端 SOCKET_EVENT_ON_LINK_CLOSE 事件已经触发【END】!', true);
                }

                //if(logined)
                {
                    // 重置在线标识，此标识只在登陆过之后才有意义（在此无条件重置吧，防止未知情况出现导致不能复位到false）
                    this._online = false;
                }

            
                if (this._debugSDKEnable) {
                    this.callback_onIMLog("[SDK]  对不起，你与IM服务器的网络连接断开了（掉线罗）...", true);
                }

                // 通知应用层网络掉线了
                if (this.callback_onIMDisconnected) {
                    this.callback_onIMDisconnected();
                }
            });

             MBCore.on(MBSocketEvent.SOCKET_EVENT_ON_RECIEVE_MESSAGE, (protocal: any) => {
                if (this._debugSDKEnable) {
                    this.callback_onIMLog('[SDK]  >> 收到[聊天消息]：' + JSON.stringify(protocal), true);
                }

                // 将收到的消息通知应用层显示出来
                this.callback_onIMData(protocal);
            });
            MBCore.on(MBSocketEvent.SOCKET_EVENT_ON_ERROR_RESPONSE, (errorResponse: any) => {
                if (this._debugSDKEnable)
                    this.callback_onIMLog("[SDK]  收到服务端错误消息，errorCode=" + errorResponse.errorCode + ", errorMsg=" + errorResponse.errorMsg, true);

            });

            MBCore.on(MBSocketEvent.SOCKET_EVENT_MESSAGE_LOST, (lostMessages: any) => {
                if (lostMessages && lostMessages.length > 0) {
                    this.callback_onIMLog('[SDK]  收到系统的未实时送达事件通知，当前共有' + lostMessages.length + '个包QoS保证机制结束，判定为【无法实时送达】！', true);

                    if (this.callback_onMessagesLost)
                        this.callback_onMessagesLost(lostMessages);
                }
            });

            MBCore.on(MBSocketEvent.SOCKET_EVENT_MESSAGE_BE_RECIEVED, (theFingerPrint: any) => {
                if (theFingerPrint) {
                    this.callback_onIMLog('[SDK]  收到对方已收到消息事件的通知，fp=' + theFingerPrint, true);

                    if (this.callback_onMessagesBeReceived)
                        this.callback_onMessagesBeReceived(theFingerPrint);
                }
            });

            /* “自动重连尝试中”事件 */
            MBCore.on(MBSocketEvent.SOCKET_EVENT_RECONNECT_ATTEMPT, (code: any) => {
                if (this._debugSDKEnable) {
                    this.callback_onIMLog('[SDK]  本客户端 SOCKET_EVENT_RECONNECT_ATTEMPT 事件已触发 (' + code + ')', true);
                }
            });

            /* 心跳包已发出事件 */
            MBCore.on(MBSocketEvent.SOCKET_EVENT_PING, () => {
                if (this._debugSDKEnable && this._debugPingPongEnable) {
                    this.callback_onIMLog('[SDK]  心跳请求已发出 →', true);
                }

                if (this.callback_onIMPing)
                    this.callback_onIMPing();
            });

            /* 心跳响应已收到事件 */
            MBCore.on(MBSocketEvent.SOCKET_EVENT_PONG, () => {
                if (this._debugSDKEnable && this._debugPingPongEnable) {
                    this.callback_onIMLog('[SDK]  心跳响应已收到 ←', true);
                }

                if (this.callback_onIMPong)
                    this.callback_onIMPong();
            });

            /* “被踢”事件（此事件由服务端检测到当前loginUserId已经别处登陆时发出） */
            MBCore.on(MBSocketEvent.SOCKET_EVENT_KICKOUT, (kickoutInfo: any) => {
                if (this._debugSDKEnable) {
                    this.callback_onIMLog('[SDK]  本客户端 SOCKET_EVENT_KICKOUT 事件已触发，kickoutInfo=' + JSON.stringify(kickoutInfo), true);
                }

                // 如果开发者已设置回调则交给开发者自行处理被踢后的应用层逻辑
                if (this.callback_onIMKickout) {
                    this.callback_onIMKickout(kickoutInfo);
                }
                // 否则直接给出提示
                else {
                    var alertContent = '';
                    if (kickoutInfo.code === MBKickoutCode.KICKOUT_FOR_DUPLICATE_LOGIN) {
                        alertContent = '账号已在其它地方登陆，当前会话已断开，请退出后重新登陆！';
                    }
                    else if (kickoutInfo.code === MBKickoutCode.KICKOUT_FOR_ADMIN) {
                        alertContent = '已被管理员强行踢出聊天，当前会话已断开！';
                    }
                    else {
                        alertContent = '你已被踢出聊天，当前会话已断开（kickoutInfo=' + JSON.stringify(kickoutInfo) + '）！';
                    }

                    // Just for debug
                    if (this._debugSDKEnable) {
                        this.callback_onIMLog('[SDK]  ' + alertContent, false);
                    }

                    // 如果开发者自已设置信息提示回调实现，就优先用开发者设置的
                    if (this.callback_onIMShowAlert) {
                        this.callback_onIMShowAlert(alertContent);
                    }
                    // 否则用浏览器默认的alert方法（就是UI有点土）
                    else {
                        window.alert(alertContent);
                    }
                }

                // 重置已经登陆过标识（此标识主要用于区分首次登陆时的界面显示）
                this._logined = false;
            });


            // 真正发出登陆请求网络指令
            var code = MBDataSender.sendLogin(varloginInfo);
            if (code === 0)
                this.callback_onIMLog('[SDK]  登陆/连接信息已发出（等待底层Socket反馈和服务端响应中...）！', true);
            else {
                this.callback_onIMLog('[SDK]  数据发送失败。错误码是：' + code + '！', true);

                var alertContent = '数据发送失败。错误码是：' + code + '！';
                // 如果开发者自已设置信息提示回调实现，就优先用开发者设置的
                if (this.callback_onIMShowAlert) {
                    this.callback_onIMShowAlert(alertContent);
                }
                // 否则用浏览器默认的alert方法（就是UI有点土）
                else {
                    window.alert(alertContent);
                }
            }
        }
        else {
            var alertContent = '无效的参数：varloginInfo=' + varloginInfo + '、wsUrl=' + wsUrl;
            // 如果开发者自已设置信息提示回调实现，就优先用开发者设置的
            if (this.callback_onIMShowAlert) {
                this.callback_onIMShowAlert(alertContent);
            }
            // 否则用浏览器默认的alert方法（就是UI有点土）
            else {
                window.alert(alertContent);
            }
        }
    }

};


export default new IMSDK